package com.hm.plugin.report.excel;

import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.hm.common.common.CommonUtil;
import com.hm.common.common.DateUtil;
import com.hm.common.common.FileUtil;
import com.hm.plugin.report.model.WriteCell;

/**
 * @author shishun.wang
 * @date 10:44:31 AM Dec 11, 2015
 * @version 1.0
 * @describe Excel 实体
 */
public class ExportExcel {

	private XSSFWorkbook workbook;
	private XSSFSheet sheet;
	private List<String> headers;
	private List<List<String>> content;
	private Set<WriteCell> headers2;
	private List<?> content2;
	private Class<?> objClass;
	private String dateFormat;
	private String tmpFilePath = "/opt/download/excel";
	
	public ExportExcel(String tmpFilePath){
		this.tmpFilePath = tmpFilePath;
		
		workbook = new XSSFWorkbook();
		sheet = workbook.createSheet("第一页");
		sheet.autoSizeColumn(1);
		sheet.autoSizeColumn(1, true);
	}
	
	public ExportExcel cusSheet (XSSFSheet sheet){
		this.sheet = sheet;
		return this;
	}
	
	public ExportExcel setDateFormat(String dateFormat) {
		this.dateFormat = dateFormat;
		return this;
	}

	public ExportExcel createSimple(){
		this.headers = new ArrayList<String>();
		return this;
	}
	
	public ExportExcel createAdvanced(){
		this.headers2 = new HashSet<WriteCell>();
		return this;
	}
	
	public ExportExcel content(List<List<String>> content){
		this.content = content;
		return this;
	}
	
	public ExportExcel content(List<?> content,Class<?> objClass){
		this.content2 = content;
		this.objClass = objClass;
		return this;
	}
	
	public void setHeader(String header){
		headers.add(header);
	}
	
	public void setCell(WriteCell cell){
		headers2.add(cell);
	}
	
	private void writeHasDF(HttpServletResponse response) throws Exception{
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		
		int rowIndex = 1;
		
		for (Object obj : content2) {
			int colIndex = 0;
			XSSFRow row = sheet.createRow(rowIndex);
			for (WriteCell cell:headers2) {
				Method method = objClass.getMethod("get"+CommonUtil.capitalize(cell.getCode()));
				method.setAccessible(true);
				Object valObj = method.invoke(obj);
				if(null != valObj){
					Class<?> valType = valObj.getClass();
					if(String.class.equals(valType)){
						row.createCell(colIndex).setCellValue(valObj.toString());
					} else if(Boolean.class.equals(valType)){
						row.createCell(colIndex).setCellValue((Boolean) valObj);
					} else if(Integer.class.equals(valType)){
						row.createCell(colIndex).setCellValue((Integer) valObj);
					} else if(Date.class.equals(valType)){
						row.createCell(colIndex).setCellValue(format.format((Date) valObj));
					}
				}else{
					row.createCell(colIndex).setCellValue("null");
				}
				colIndex ++;
			}
			rowIndex ++;
		}
	}
	
	private void writeNotHasDF(HttpServletResponse response) throws Exception{
		int rowIndex = 1;
		for (Object obj : content2) {
			int colIndex = 0;
			XSSFRow row = sheet.createRow(rowIndex);
			for (WriteCell cell:headers2) {
				Method method = objClass.getMethod("get"+CommonUtil.capitalize(cell.getCode()));
				method.setAccessible(true);
				Object valObj = method.invoke(obj);
				if(null != valObj){
					Class<?> valType = valObj.getClass();
					if(String.class.equals(valType)){
						row.createCell(colIndex).setCellValue(valObj.toString());
					} else if(Boolean.class.equals(valType)){
						row.createCell(colIndex).setCellValue((Boolean) valObj);
					} else if(Integer.class.equals(valType)){
						row.createCell(colIndex).setCellValue((Integer) valObj);
					} else if(Date.class.equals(valType)){
						row.createCell(colIndex).setCellValue(DateUtil.yyyyMMddhhmm((Date)valObj));
					}
				}else{
					row.createCell(colIndex).setCellValue("null");
				}
				colIndex ++;
			}
			rowIndex ++;
		}
	}
	
	public String getPath() throws Exception{
		String path = FileUtil.generationNewFilePath(tmpFilePath);
		{//判断文件夹存在否
			FileUtil.exists(path, true);
		}
		path += "/"+UUID.randomUUID()+".xls";
		return path;
	}
	
	public void write2(HttpServletResponse response) throws Exception{
		String path = getPath();
		//创建表头
		XSSFRow row = sheet.createRow(0);
		int index = 0;
		for (WriteCell cell:headers2) {
			XSSFCell createCell = row.createCell(index);
			createCell.setCellValue(cell.getName());
			createCell.setCellStyle(cell.getStyle());
			index ++;
		}
		//写入excel内容
		if(null != this.dateFormat){
			this.writeHasDF(response);
		}else{
			this.writeNotHasDF(response);
		}
		
		workbook.write(new FileOutputStream(path));
		FileUtil.download(path, System.currentTimeMillis()+".xls", response);
	}
	
	public void write(HttpServletResponse response) throws Exception{
		String path = getPath();
		long cols = headers.size();
		{//写入excel头
			XSSFRow row = sheet.createRow(0);
			for (int i = 0; i < cols; i++) {
				row.createCell(i).setCellValue(headers.get(i));
			}
		}
		//写内容
		for (int j = 0; j < content.size(); j++) {
			XSSFRow row = sheet.createRow(j + 1);
			
			List<String> list = content.get(j);
			for (int i = 0; i < cols; i++) {
				row.createCell(i).setCellValue(list.get(i));
			}
		}
		workbook.write(new FileOutputStream(path));
		
		FileUtil.download(path, System.currentTimeMillis()+".xls", response);
		{//删除临时文件
			FileUtil.deleteFile(path);
		}
	}
	
}
